;;! multi_memory = true
;;! threads = true
;;! memory64 = true
;;! custom_page_sizes = true

;; generate the cross product of:
;;
;; * maximum listed: {no, yes}
;; * page size: {1<<16, 1}
;; * shared: {no, yes}
;; * index type: {i32, i64}
(module
  (memory $m1 1)
  (memory $m2 1 65536)
  (memory $m3 1 (pagesize 1))
  (memory $m4 1 0xffff_ffff (pagesize 1))

  ;; (memory $m5 1 shared) - skipped since shared requires max size
  (memory $m6 1 65536 shared)
  ;; (memory $m7 1 (pagesize 1)) - skipped since shared requires max size
  (memory $m8 1 0xffff_ffff shared (pagesize 1))

  (memory $m9 i64 1)
  (memory $m10 i64 1 65536)
  (memory $m11 i64 1 (pagesize 1))
  (memory $m12 i64 1 0xffff_ffff (pagesize 1))

  ;; (memory $m13 1 shared) - skipped since shared requires max size
  (memory $m14 i64 1 65536 shared)
  ;; (memory $m16 1 (pagesize 1)) - skipped since shared requires max size
  (memory $m16 i64 1 0xffff_ffff shared (pagesize 1))

  (func (export "load_m1") (param i32) (result i32) (i32.load8_u $m1 (local.get 0)))
  (func (export "load_m2") (param i32) (result i32) (i32.load8_u $m2 (local.get 0)))
  (func (export "load_m3") (param i32) (result i32) (i32.load8_u $m3 (local.get 0)))
  (func (export "load_m4") (param i32) (result i32) (i32.load8_u $m4 (local.get 0)))
  (func (export "load_m6") (param i32) (result i32) (i32.load8_u $m6 (local.get 0)))
  (func (export "load_m8") (param i32) (result i32) (i32.load8_u $m8 (local.get 0)))
  (func (export "load_m9") (param i64) (result i32) (i32.load8_u $m9 (local.get 0)))
  (func (export "load_m10") (param i64) (result i32) (i32.load8_u $m10 (local.get 0)))
  (func (export "load_m11") (param i64) (result i32) (i32.load8_u $m11 (local.get 0)))
  (func (export "load_m12") (param i64) (result i32) (i32.load8_u $m12 (local.get 0)))
  (func (export "load_m14") (param i64) (result i32) (i32.load8_u $m14 (local.get 0)))
  (func (export "load_m16") (param i64) (result i32) (i32.load8_u $m16 (local.get 0)))

  (func (export "store_m1") (param i32 i32) (i32.store8 $m1 (local.get 0) (local.get 1)))
  (func (export "store_m2") (param i32 i32) (i32.store8 $m2 (local.get 0) (local.get 1)))
  (func (export "store_m3") (param i32 i32) (i32.store8 $m3 (local.get 0) (local.get 1)))
  (func (export "store_m4") (param i32 i32) (i32.store8 $m4 (local.get 0) (local.get 1)))
  (func (export "store_m6") (param i32 i32) (i32.store8 $m6 (local.get 0) (local.get 1)))
  (func (export "store_m8") (param i32 i32) (i32.store8 $m8 (local.get 0) (local.get 1)))
  (func (export "store_m9") (param i64 i32) (i32.store8 $m9 (local.get 0) (local.get 1)))
  (func (export "store_m10") (param i64 i32) (i32.store8 $m10 (local.get 0) (local.get 1)))
  (func (export "store_m11") (param i64 i32) (i32.store8 $m11 (local.get 0) (local.get 1)))
  (func (export "store_m12") (param i64 i32) (i32.store8 $m12 (local.get 0) (local.get 1)))
  (func (export "store_m14") (param i64 i32) (i32.store8 $m14 (local.get 0) (local.get 1)))
  (func (export "store_m16") (param i64 i32) (i32.store8 $m16 (local.get 0) (local.get 1)))

  (func (export "grow_m1") (param i32) (result i32) (memory.grow $m1 (local.get 0)))
  (func (export "grow_m2") (param i32) (result i32) (memory.grow $m2 (local.get 0)))
  (func (export "grow_m3") (param i32) (result i32) (memory.grow $m3 (local.get 0)))
  (func (export "grow_m4") (param i32) (result i32) (memory.grow $m4 (local.get 0)))
  (func (export "grow_m6") (param i32) (result i32) (memory.grow $m6 (local.get 0)))
  (func (export "grow_m8") (param i32) (result i32) (memory.grow $m8 (local.get 0)))
  (func (export "grow_m9") (param i64) (result i64) (memory.grow $m9 (local.get 0)))
  (func (export "grow_m10") (param i64) (result i64) (memory.grow $m10 (local.get 0)))
  (func (export "grow_m11") (param i64) (result i64) (memory.grow $m11 (local.get 0)))
  (func (export "grow_m12") (param i64) (result i64) (memory.grow $m12 (local.get 0)))
  (func (export "grow_m14") (param i64) (result i64) (memory.grow $m14 (local.get 0)))
  (func (export "grow_m16") (param i64) (result i64) (memory.grow $m16 (local.get 0)))

  (func (export "size_m1") (result i32) (memory.size $m1))
  (func (export "size_m2") (result i32) (memory.size $m2))
  (func (export "size_m3") (result i32) (memory.size $m3))
  (func (export "size_m4") (result i32) (memory.size $m4))
  (func (export "size_m6") (result i32) (memory.size $m6))
  (func (export "size_m8") (result i32) (memory.size $m8))
  (func (export "size_m9") (result i64) (memory.size $m9))
  (func (export "size_m10") (result i64) (memory.size $m10))
  (func (export "size_m11") (result i64) (memory.size $m11))
  (func (export "size_m12") (result i64) (memory.size $m12))
  (func (export "size_m14") (result i64) (memory.size $m14))
  (func (export "size_m16") (result i64) (memory.size $m16))
)

(assert_return (invoke "load_m1" (i32.const 0)) (i32.const 0))
(assert_return (invoke "store_m1" (i32.const 0) (i32.const 1)))
(assert_return (invoke "load_m1" (i32.const 0)) (i32.const 1))
(assert_return (invoke "size_m1") (i32.const 1))
(assert_trap (invoke "load_m1" (i32.const 65536)) "out of bounds memory access")
(assert_trap (invoke "store_m1" (i32.const 65536) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m1" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m1" (i32.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m1" (i32.const 1)) (i32.const 1))
(assert_return (invoke "size_m1") (i32.const 2))
(assert_return (invoke "grow_m1" (i32.const -1)) (i32.const -1))
(assert_return (invoke "load_m1" (i32.const 65536)) (i32.const 0))
(assert_return (invoke "store_m1" (i32.const 65536) (i32.const 1)))
(assert_return (invoke "load_m1" (i32.const 65536)) (i32.const 1))
(assert_trap (invoke "load_m1" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m1" (i32.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m2" (i32.const 0)) (i32.const 0))
(assert_return (invoke "store_m2" (i32.const 0) (i32.const 1)))
(assert_return (invoke "load_m2" (i32.const 0)) (i32.const 1))
(assert_return (invoke "size_m2") (i32.const 1))
(assert_trap (invoke "load_m2" (i32.const 65536)) "out of bounds memory access")
(assert_trap (invoke "store_m2" (i32.const 65536) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m2" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m2" (i32.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m2" (i32.const 1)) (i32.const 1))
(assert_return (invoke "size_m2") (i32.const 2))
(assert_return (invoke "grow_m2" (i32.const -1)) (i32.const -1))
(assert_return (invoke "load_m2" (i32.const 65536)) (i32.const 0))
(assert_return (invoke "store_m2" (i32.const 65536) (i32.const 1)))
(assert_return (invoke "load_m2" (i32.const 65536)) (i32.const 1))
(assert_trap (invoke "load_m2" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m2" (i32.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m3" (i32.const 0)) (i32.const 0))
(assert_return (invoke "store_m3" (i32.const 0) (i32.const 1)))
(assert_return (invoke "load_m3" (i32.const 0)) (i32.const 1))
(assert_return (invoke "size_m3") (i32.const 1))
(assert_trap (invoke "load_m3" (i32.const 1)) "out of bounds memory access")
(assert_trap (invoke "store_m3" (i32.const 1) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m3" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m3" (i32.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m3" (i32.const 1)) (i32.const 1))
(assert_return (invoke "size_m3") (i32.const 2))
(assert_return (invoke "grow_m3" (i32.const -1)) (i32.const -1))
(assert_return (invoke "load_m3" (i32.const 1)) (i32.const 0))
(assert_return (invoke "store_m3" (i32.const 1) (i32.const 1)))
(assert_return (invoke "load_m3" (i32.const 1)) (i32.const 1))
(assert_trap (invoke "load_m3" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m3" (i32.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m4" (i32.const 0)) (i32.const 0))
(assert_return (invoke "store_m4" (i32.const 0) (i32.const 1)))
(assert_return (invoke "load_m4" (i32.const 0)) (i32.const 1))
(assert_return (invoke "size_m4") (i32.const 1))
(assert_trap (invoke "load_m4" (i32.const 1)) "out of bounds memory access")
(assert_trap (invoke "store_m4" (i32.const 1) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m4" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m4" (i32.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m4" (i32.const 1)) (i32.const 1))
(assert_return (invoke "size_m4") (i32.const 2))
(assert_return (invoke "grow_m4" (i32.const -1)) (i32.const -1))
(assert_return (invoke "load_m4" (i32.const 1)) (i32.const 0))
(assert_return (invoke "store_m4" (i32.const 1) (i32.const 1)))
(assert_return (invoke "load_m4" (i32.const 1)) (i32.const 1))
(assert_trap (invoke "load_m4" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m4" (i32.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m6" (i32.const 0)) (i32.const 0))
(assert_return (invoke "store_m6" (i32.const 0) (i32.const 1)))
(assert_return (invoke "load_m6" (i32.const 0)) (i32.const 1))
(assert_return (invoke "size_m6") (i32.const 1))
(assert_trap (invoke "load_m6" (i32.const 65536)) "out of bounds memory access")
(assert_trap (invoke "store_m6" (i32.const 65536) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m6" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m6" (i32.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m6" (i32.const 1)) (i32.const 1))
(assert_return (invoke "size_m6") (i32.const 2))
(assert_return (invoke "grow_m6" (i32.const -1)) (i32.const -1))
(assert_return (invoke "load_m6" (i32.const 65536)) (i32.const 0))
(assert_return (invoke "store_m6" (i32.const 65536) (i32.const 1)))
(assert_return (invoke "load_m6" (i32.const 65536)) (i32.const 1))
(assert_trap (invoke "load_m6" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m6" (i32.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m8" (i32.const 0)) (i32.const 0))
(assert_return (invoke "store_m8" (i32.const 0) (i32.const 1)))
(assert_return (invoke "load_m8" (i32.const 0)) (i32.const 1))
(assert_return (invoke "size_m8") (i32.const 1))
(assert_trap (invoke "load_m8" (i32.const 1)) "out of bounds memory access")
(assert_trap (invoke "store_m8" (i32.const 1) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m8" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m8" (i32.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m8" (i32.const 1)) (i32.const 1))
(assert_return (invoke "size_m8") (i32.const 2))
(assert_return (invoke "grow_m8" (i32.const -1)) (i32.const -1))
(assert_return (invoke "load_m8" (i32.const 1)) (i32.const 0))
(assert_return (invoke "store_m8" (i32.const 1) (i32.const 1)))
(assert_return (invoke "load_m8" (i32.const 1)) (i32.const 1))
(assert_trap (invoke "load_m8" (i32.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m8" (i32.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m9" (i64.const 0)) (i32.const 0))
(assert_return (invoke "store_m9" (i64.const 0) (i32.const 1)))
(assert_return (invoke "load_m9" (i64.const 0)) (i32.const 1))
(assert_return (invoke "size_m9") (i64.const 1))
(assert_trap (invoke "load_m9" (i64.const 65536)) "out of bounds memory access")
(assert_trap (invoke "store_m9" (i64.const 65536) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m9" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m9" (i64.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m9" (i64.const 1)) (i64.const 1))
(assert_return (invoke "size_m9") (i64.const 2))
(assert_return (invoke "grow_m9" (i64.const -1)) (i64.const -1))
(assert_return (invoke "load_m9" (i64.const 65536)) (i32.const 0))
(assert_return (invoke "store_m9" (i64.const 65536) (i32.const 1)))
(assert_return (invoke "load_m9" (i64.const 65536)) (i32.const 1))
(assert_trap (invoke "load_m9" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m9" (i64.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m10" (i64.const 0)) (i32.const 0))
(assert_return (invoke "store_m10" (i64.const 0) (i32.const 1)))
(assert_return (invoke "load_m10" (i64.const 0)) (i32.const 1))
(assert_return (invoke "size_m10") (i64.const 1))
(assert_trap (invoke "load_m10" (i64.const 65536)) "out of bounds memory access")
(assert_trap (invoke "store_m10" (i64.const 65536) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m10" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m10" (i64.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m10" (i64.const 1)) (i64.const 1))
(assert_return (invoke "size_m10") (i64.const 2))
(assert_return (invoke "grow_m10" (i64.const -1)) (i64.const -1))
(assert_return (invoke "load_m10" (i64.const 65536)) (i32.const 0))
(assert_return (invoke "store_m10" (i64.const 65536) (i32.const 1)))
(assert_return (invoke "load_m10" (i64.const 65536)) (i32.const 1))
(assert_trap (invoke "load_m10" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m10" (i64.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m11" (i64.const 0)) (i32.const 0))
(assert_return (invoke "store_m11" (i64.const 0) (i32.const 1)))
(assert_return (invoke "load_m11" (i64.const 0)) (i32.const 1))
(assert_return (invoke "size_m11") (i64.const 1))
(assert_trap (invoke "load_m11" (i64.const 1)) "out of bounds memory access")
(assert_trap (invoke "store_m11" (i64.const 1) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m11" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m11" (i64.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m11" (i64.const 1)) (i64.const 1))
(assert_return (invoke "size_m11") (i64.const 2))
(assert_return (invoke "grow_m11" (i64.const -1)) (i64.const -1))
(assert_return (invoke "load_m11" (i64.const 1)) (i32.const 0))
(assert_return (invoke "store_m11" (i64.const 1) (i32.const 1)))
(assert_return (invoke "load_m11" (i64.const 1)) (i32.const 1))
(assert_trap (invoke "load_m11" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m11" (i64.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m12" (i64.const 0)) (i32.const 0))
(assert_return (invoke "store_m12" (i64.const 0) (i32.const 1)))
(assert_return (invoke "load_m12" (i64.const 0)) (i32.const 1))
(assert_return (invoke "size_m12") (i64.const 1))
(assert_trap (invoke "load_m12" (i64.const 1)) "out of bounds memory access")
(assert_trap (invoke "store_m12" (i64.const 1) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m12" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m12" (i64.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m12" (i64.const 1)) (i64.const 1))
(assert_return (invoke "size_m12") (i64.const 2))
(assert_return (invoke "grow_m12" (i64.const -1)) (i64.const -1))
(assert_return (invoke "load_m12" (i64.const 1)) (i32.const 0))
(assert_return (invoke "store_m12" (i64.const 1) (i32.const 1)))
(assert_return (invoke "load_m12" (i64.const 1)) (i32.const 1))
(assert_trap (invoke "load_m12" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m12" (i64.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m14" (i64.const 0)) (i32.const 0))
(assert_return (invoke "store_m14" (i64.const 0) (i32.const 1)))
(assert_return (invoke "load_m14" (i64.const 0)) (i32.const 1))
(assert_return (invoke "size_m14") (i64.const 1))
(assert_trap (invoke "load_m14" (i64.const 65536)) "out of bounds memory access")
(assert_trap (invoke "store_m14" (i64.const 65536) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m14" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m14" (i64.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m14" (i64.const 1)) (i64.const 1))
(assert_return (invoke "size_m14") (i64.const 2))
(assert_return (invoke "grow_m14" (i64.const -1)) (i64.const -1))
(assert_return (invoke "load_m14" (i64.const 65536)) (i32.const 0))
(assert_return (invoke "store_m14" (i64.const 65536) (i32.const 1)))
(assert_return (invoke "load_m14" (i64.const 65536)) (i32.const 1))
(assert_trap (invoke "load_m14" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m14" (i64.const -1) (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "load_m16" (i64.const 0)) (i32.const 0))
(assert_return (invoke "store_m16" (i64.const 0) (i32.const 1)))
(assert_return (invoke "load_m16" (i64.const 0)) (i32.const 1))
(assert_return (invoke "size_m16") (i64.const 1))
(assert_trap (invoke "load_m16" (i64.const 1)) "out of bounds memory access")
(assert_trap (invoke "store_m16" (i64.const 1) (i32.const 0)) "out of bounds memory access")
(assert_trap (invoke "load_m16" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m16" (i64.const -1) (i32.const 0)) "out of bounds memory access")
(assert_return (invoke "grow_m16" (i64.const 1)) (i64.const 1))
(assert_return (invoke "size_m16") (i64.const 2))
(assert_return (invoke "grow_m16" (i64.const -1)) (i64.const -1))
(assert_return (invoke "load_m16" (i64.const 1)) (i32.const 0))
(assert_return (invoke "store_m16" (i64.const 1) (i32.const 1)))
(assert_return (invoke "load_m16" (i64.const 1)) (i32.const 1))
(assert_trap (invoke "load_m16" (i64.const -1)) "out of bounds memory access")
(assert_trap (invoke "store_m16" (i64.const -1) (i32.const 0)) "out of bounds memory access")
